﻿// <copyright file="QueueProvider.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains the QueueProvider provider</summary>

namespace Sqwarea.Persistence.Azure
{
    using System;
    using Lokad.Cloud.Storage;

    /// <summary>
    /// Provider for queues used to store connexity breakpoints and new king Id's 
    /// </summary>
    public class QueueProvider : IQueueProvider
    {
        /// <summary>
        /// Name of the Queue in which the Attacks will enventually end up.
        /// </summary>
        public const string NewKingQueueName = "sqwarea-new-king-queue";

        /// <summary>
        /// Name of the Queue in which the Breakpoints for connexity are placed.
        /// </summary>
        public const string ConnexityBreakPointQueueName = "sqwarea-connexity-break-point-queue";

        /// <summary>
        /// Name of the Queue in which the kings we need to correct connexity are placed.
        /// </summary>
        public const string ConnexityKingToCorrectQueueName = "sqwarea-connexity-king-correct-queue";

        /// <summary>
        /// Name of the Queue in which the Kings that must have their attack table cleaned are placed
        /// </summary>
        public const string CleanableKingIdQueueName = "sqwarea-cleanable-king-queue";

        /// <summary>
        /// Queue provider
        /// </summary>
        private readonly IQueueStorageProvider _queueProvider;

        /// <summary>
        /// Initializes a new instance of the QueueProvider class.
        /// </summary>
        /// <param name="queueProvider"> a queue provider</param>
        [CLSCompliantAttribute(false)]
        public QueueProvider(IQueueStorageProvider queueProvider)
        {
            if (null == queueProvider)
            {
                throw new ArgumentNullException("queueProvider", "queueProvider must not be null");
            }

            _queueProvider = queueProvider;
        }

        /// <summary>
        /// Gets the length of the "NewKingsId" queue.
        /// </summary>
        /// <returns>See summary.</returns>
        public int GetNewKingsIdQueueLength()
        {
            return _queueProvider.GetApproximateCount(NewKingQueueName);
        }

        /// <summary>
        /// Gets the length of the "ConnexityKingToCorrect" queue.
        /// </summary>
        /// <returns>See summary.</returns>
        public int GetConnexityKingQueueLength()
        {
            return _queueProvider.GetApproximateCount(ConnexityKingToCorrectQueueName);
        }

        /// <summary>
        /// Gets the length of the "CleanableKingId" queue.
        /// </summary>
        /// <returns>See summary.</returns>
        public int GetCleanableKingIdQueueLength()
        {
            return _queueProvider.GetApproximateCount(CleanableKingIdQueueName);
        }

        /// <summary>
        /// Puts id from start to start+count-1 in "NewKingId" queue.
        /// </summary>
        /// <param name="start">First id to put in the queue</param>
        /// <param name="count">Number of ids to put in the queue</param>
        public void PutNewKingsId(long start, long count)
        {
            _queueProvider.PutRange(NewKingQueueName, Tools.Range(start, count));
        }

        /// <summary>
        /// Puts a ConnexityBreakPoint in the "ConnexityBreakPoint" queue.
        /// </summary>
        /// <param name="connexityBreakPoint">The ConnexityBreakPoint</param>
        public void PutConnexityBreakPoint(ConnexityBreakpoint connexityBreakPoint)
        {
            _queueProvider.Put(ConnexityBreakPointQueueName, connexityBreakPoint);
        }

        /// <summary>
        /// Puts a king Id in the "ConnexityKingToCorrect" queue.
        /// </summary>
        /// <param name="kingId">The Id of the King</param>
        public void PutConnexityKingToCorrect(long kingId)
        {
            _queueProvider.Put(ConnexityKingToCorrectQueueName, kingId);
        }
        
        /// <summary>
        /// Adds a King to the list of king that must get their temporary attacks table cleaned
        /// </summary>
        /// <param name="kingId">Id of the king.</param>
        public void PutKingToClean(long kingId)
        {
            _queueProvider.Put(CleanableKingIdQueueName, kingId);
        }
    }
}
